﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace HCMUS_SearchService_Group2
{
    /////////////////////////////////////////////////
    /// \brief Lớp truy xuất dữ liệu từ bảng DULIEU của CSDL.
    /// \details <h3>Cung cấp các phương thức để truy xuất dữ liệu từ CSDL</h3>
    /////////////////////////////////////////////////
    public class DataDAO : DataConnectionHelper
    {
        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<DULIEU> listData.
        /// \returns List<DataDTO>.
        /// \details <h3>Giúp chuyển đổi List<DULIEU> sang List<DataDTO>.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> ConvertoDataDTO(List<DULIEU> listData)
        {
            List<DataDTO> listDataDTO = new List<DataDTO>();
            foreach (var data in listData)
            {
                DataDTO temp = new DataDTO() { MaDichVu = Convert.ToInt32(data.MaDichVu), MaDuLieu = data.MaDuLieu, MaDuong = Convert.ToInt32(data.MaDuong), MaPhuong = Convert.ToInt32(data.MaPhuong), MaQuanHuyen = Convert.ToInt32(data.MaQuanHuyen), MaTenDiaDiem = Convert.ToInt32(data.MaTenDiaDiem), MaTinhThanh = Convert.ToInt32(data.MaTinhThanh), SoNha = data.SoNha, KinhDo = (double)data.KinhDo, ViDo = (double)data.ViDo};
                listDataDTO.Add(temp);
            }

            return listDataDTO;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm lấy dữ liệu
        /// \returns List<ObjectDTO>.
        /// \details <h3>Lấy toàn bộ dữ liệu của bảng DULIEU.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> GetAllDTO()
        {
            List<DULIEU> listData = new List<DULIEU>();

            /// - Bước 1: Lấy toàn bộ dữ liệu từ bảng DULIEU của CSDL. 
            listData = (
                from emp in DataConnectionHelper.Context.DULIEUs
                select emp).ToList();

            /// - Bước 2: Thực hiện chuyển đổi List<DULIEU> sang List<DataDTO> trước khi return giá trị. 
            return DataDAO.ConvertoDataDTO(listData);
        }

        /////////////////////////////////////////////////
        /// \brief Hàm lấy dữ liệu
        /// \param[in] string address.
        /// \param[in] int idService.
        /// \param[in] int idCity.
        /// \param[in] int idDistrict.
        /// \param[in] int idWard.
        /// \param[in] int idStreet.
        /// \param[in] int idLocation.
        /// \returns List<DataDTO>.
        /// \details <h3>Trả về List các đối tượng DataDTO  .</h3>
        /////////////////////////////////////////////////
        /*   public List<DataDTO> Search(string address, int idService, int idCity, int idDistrict, int idWard, int idStreet, int idLocation)
           {
               List<int> parameters = new List<int>() { idService, idCity, idDistrict, idWard, idStreet, idLocation };
               List<DULIEU> listData = new List<DULIEU>();
               List<DataDTO> listDataDTO = new List<DataDTO>();
            
               IQueryable<DULIEU> dataQuery = DataConnectionHelper.Context.DULIEUs.AsQueryable<DULIEU>();
                        
               ParameterExpression data = System.Linq.Expressions.Expression.Parameter(typeof(DULIEU), "data");
               MethodInfo containsmi = typeof(int).GetMethod("Equals", new[] { typeof(int) });
               MethodInfo method = typeof(string).GetMethod("Equals", new[] { typeof(string) });            
               List<System.Linq.Expressions.Expression> exProperty = new List<System.Linq.Expressions.Expression>();
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("SoNha")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaDichVu")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaTinhThanh")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaQuanHuyen")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaPhuong")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaDuong")));
               exProperty.Add(System.Linq.Expressions.Expression.Property(data, typeof(DULIEU).GetProperty("MaTenDiaDiem")));

               System.Linq.Expressions.Expression expression = null;
               System.Linq.Expressions.Expression right;
               if (!string.IsNullOrEmpty(address))
               {
                   right = System.Linq.Expressions.Expression.Constant(address, typeof(string));
                   expression = System.Linq.Expressions.Expression.Call(exProperty[0], method, new System.Linq.Expressions.Expression[] { right });
                   for (int i = 1; i < exProperty.Count; i++)
                   {
                       if (parameters[i - 1] != DataConnectionHelper._defaultNumber)
                       {
                           right = System.Linq.Expressions.Expression.Constant(parameters[i - 1], typeof(int));
                           expression = System.Linq.Expressions.Expression.AndAlso(expression, System.Linq.Expressions.Expression.Call(exProperty[i], containsmi, new System.Linq.Expressions.Expression[] { right }));
                       }
                   }
               }
               else
               {
                   bool flag = true;
                   for (int i = 0; i < parameters.Count; i++)
                   {
                       if (parameters[i] != DataConnectionHelper._defaultNumber && flag == true)
                       {
                           right = System.Linq.Expressions.Expression.Constant(parameters[i], typeof(int?));
                           expression = System.Linq.Expressions.Expression.Equal(exProperty[i + 1], right);
                           flag = false;
                           continue;
                       }

                       if (parameters[i] != DataConnectionHelper._defaultNumber && flag == false)
                       {
                           right = System.Linq.Expressions.Expression.Constant(parameters[i], typeof(int));
                           expression = System.Linq.Expressions.Expression.AndAlso(expression, System.Linq.Expressions.Expression.Call(exProperty[i + 1], containsmi, new System.Linq.Expressions.Expression[] { right }));
                       }
                   }
               }

               MethodCallExpression whereCallExpression = System.Linq.Expressions.Expression.Call(typeof(Queryable),
                   "Where",
                   new Type[] { dataQuery.ElementType },
                   dataQuery.Expression,
                   System.Linq.Expressions.Expression.Lambda<Func<DULIEU, bool>>(expression, new ParameterExpression[] { data }));

               IQueryable<DULIEU> result = dataQuery.Provider.CreateQuery<DULIEU>(whereCallExpression);

               return this.ConvertoDataDTO(result.ToList());
           }*/

        public static List<DataDTO> Search(SearchResultObject searchObject)
        {
            List<DataDTO> lstDuLieuDTO = new List<DataDTO>();
            int notSearchNumber = DataConnectionHelper._defaultNumber;
            IEnumerable<DataDTO> query = new List<DataDTO>();
            
            if(searchObject.isNullObject())
            {
                return lstDuLieuDTO;
            }

            query = from data in SearchHelper.Datas
                    where (notSearchNumber == searchObject.ServiceID || searchObject.ServiceID == Convert.ToInt32(data.MaDichVu)) &&
                    (notSearchNumber == searchObject.StreetID || searchObject.StreetID == Convert.ToInt32(data.MaDuong)) &&
                    (notSearchNumber == searchObject.LocationID || searchObject.LocationID == Convert.ToInt32(data.MaTenDiaDiem)) &&
                    (notSearchNumber == searchObject.DistrictID || searchObject.DistrictID == Convert.ToInt32(data.MaQuanHuyen)) &&
                    (notSearchNumber == searchObject.WardID || searchObject.WardID == Convert.ToInt32(data.MaPhuong)) &&
                    (notSearchNumber == searchObject.CityID || searchObject.CityID == Convert.ToInt32(data.MaTinhThanh)) &&
                    (searchObject.Location == data.SoNha || (null == searchObject.Location || searchObject.Location.Length == 0))
                    select data;

            return query.ToList();
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string strInput.
        /// \returns List<DataDTO>.
        /// \details <h3>Tìm kiếm các đối tượng DataDTO có SoNha chứa chuỗi strInput cần tìm.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> SearchWithSoNha(string strInput)
        {
            List<DataDTO> listData = new List<DataDTO>();
            strInput = strInput.Replace(@"'", @"''");

            /// - Bước 1: Tìm kiếm các đối tượng DataDTO có SoNha chứa chuỗi strInput. 
            listData = (
                  from data in SearchHelper.Datas
                  where strInput.IndexOf(data.SoNha) != -1
                  select data).Take(10).ToList();

            /// - Bước 2: Thực hiện chuyển đổi List<DULIEU> sang List<DataDTO> trước khi return giá trị. 
            return listData;
        }
    }
}